#ifndef T_BOX_SEQUENCE_H
#define T_BOX_SEQUENCE_H

#include "core/core.h"
//#include "stable.h"
//#include "core/nbr.h"

class T_Box_Sequence_Proxy;

class T_Box_Sequence : public T_RecursiveAtomic
{
    friend class T_Box_Sequence_Proxy;
public:
    explicit T_Box_Sequence()
    {  }
    virtual T_Box_Sequence_Proxy *open();
    virtual QString displayName();
    virtual void displayName(const QString &a_name);
    virtual bool isValid() = 0;
protected:
    virtual bool isFinished() = 0;
    virtual int bufferSize() = 0;
    virtual QString displayNameDefault() = 0;
    virtual qint64 availableSize() = 0;
    virtual qint64 expectedSize() = 0;
    virtual qint64 pos() = 0;
    virtual bool seek(qint64 a_offset) = 0;
    virtual QByteArray wait_read(qint64 a_max_size) = 0;
protected:
    QString m_name;
};

class T_Box_Sequence_Proxy
{
    friend class T_Box_Sequence;
public:
    virtual bool isValid();
    virtual int bufferSize();
    virtual QString displayName();
    virtual qint64 expectedSize();
    virtual qint64 pos();
    virtual bool seek(qint64 a_offset);
    virtual QByteArray wait_read(qint64 a_max_size);
protected:
    explicit T_Box_Sequence_Proxy(T_Box_Sequence *a_seq);
    virtual bool isFinished();
    virtual qint64 availableSize();
    void p_wait_one_step();
protected:
    T_Box_Sequence *m_seq;
    qint64 m_pos;
};

class T_Box_Sequence_File : public T_Box_Sequence
{
protected:
    QFile m_file;
public:
    explicit T_Box_Sequence_File(const QString &a_filename)
        : m_file(a_filename)
    {
        m_file.open(QIODevice::ReadOnly);
    }
    virtual ~T_Box_Sequence_File()
    {
        m_file.close();
    }
protected:
    virtual bool isValid()
    {
        return m_file.isOpen();
    }
    virtual bool isFinished()
    {
        return true;
    }
    virtual int bufferSize()
    {
        return 32768;
    }
    virtual QString displayNameDefault()
    {
        return m_file.fileName();
    }
    virtual qint64 expectedSize()
    {
        return m_file.size();
    }
    virtual qint64 availableSize()
    {
        return m_file.size();
    }
    virtual qint64 pos()
    {
        return m_file.pos();
    }
    virtual bool seek(qint64 a_offset)
    {
        return m_file.seek(a_offset);
    }
    virtual QByteArray wait_read(qint64 a_max_size)
    {
        return m_file.read(a_max_size);
    }
};

class T_Box_Sequence_Http : public T_Box_Sequence
{
protected:
    QNetworkReply *m_reply;
    NetworkSequence m_net_seq;
    bool m_is_valid;
public:

    explicit T_Box_Sequence_Http(QNetworkReply *a_reply)
        : m_reply(a_reply)
        , m_net_seq(a_reply)
        , m_is_valid(false)
    {
        m_is_valid = true;
    }
    virtual ~T_Box_Sequence_Http()
    {
    }
    bool isValid()
    {
        return m_is_valid;
    }
    virtual bool isFinished()
    {
        return m_net_seq.isFinished();
    }
    int bufferSize()
    {
        return 4096;
    }
    virtual QString displayNameDefault()
    {
        return m_reply->url().toString();
    }
    qint64 expectedSize()
    {
        return m_net_seq.expectedSize();
    }
    virtual qint64 availableSize()
    {
        return m_net_seq.availableSize();
    }
    qint64 pos()
    {
        return m_net_seq.pos();
    }
    bool seek(qint64 offset)
    {
        return m_net_seq.seek(offset);
    }
    QByteArray wait_read(qint64 a_max_size)
    {
        return m_net_seq.wait_read(a_max_size);
    }
};

#endif // T_BOX_SEQUENCE_H
